/**
 * @author casazaft
 */
//基础类库
(function(){
    Package("j2j.lang").Class("Object", {
        //构造函数
        Object: function(){
             this._j2jhash = j2j.unique();
        },
        Statics: {
        
            getName: function(){
                return this._name;
            }
        },
        Prototype: {
            clone: function(){
                throw Error("do not support clone now!");
            },
            hashCode: function(){
                return this._j2jhash;
            },
            getClass: function(){
                return this._classRef;
            },
            toString: function(){
                var str = [];
                for (var p in this) {
                    if (this[p] === this) {
                        continue;
                    }
                    str[str.length] = p + ":" + this[p].toString();
                }
                str = str.join(",");
                str = "{" + str + "}";
                return str;
            },
            equals: function(obj){
                var result = false;
                for (var p in this) {
                    if (this[p].equals) {
                        result = this[p].equals(obj[p]);
                    }
                    else {
                        result = (this[p] === obj[p]);
                    }
                    if (!result) {
                        log.info(j2j.lang.Object.prototype.toString.apply(this[p]));
                        log.info(j2j.lang.Object.prototype.toString.apply(obj[p]));
                        return result;
                    }
                }
                return result;
            },
            finalize: function(){
               j2j.lang.System.setGC(this);
            }
        },
        Extends: Object
    });
    
    Package("j2j.patterns").Class("Singleton",{
	Singleton:function(){
		             var thisClass = this.getClass();
            if (typeof thisClass._instance == 'function') 
                thisClass._instance = new thisClass._instance();
            if (thisClass._instance.getInstance() != null) 
                throw Error("Class " + this.Name + thisClass.SINGLETON_MSG);
            thisClass._instance.setInstance(this);
        },
        Statics: {
            _instance: function(){
                var instance = null;
                return {
                    getInstance: function(){
                        return instance;
                    },
                    setInstance: function(p){
                        instance = p;
                    }
                };
            },
            SINGLETON_MSG: ' is Singleton',
            getInstance: function(){
                if (typeof this._instance == 'function') 
                    this._instance = new this._instance();
                if (this._instance.getInstance() == null) {
                    var classRef = this;
                    this._instance.setInstance(new classRef(arguments));
                }
                return this._instance.getInstance();
            }
        }
    });
    
    Package("j2j.io").Class("PrintStream",{
	PrintStream:function(){
		             var pRe = /\{(\d+)\}/;
            this.format = function(str){
                var match, vp, rp;
                match = str.match(pRe);
                if (!match) {
                    return str;
                }
                while (match) {
                    vp = match[1];
                    rp = parseInt(vp, 10) + 1;
                    rp = arguments[rp] + "";
                    if (!rp) {
                        throw Error("numbers of argument is no enough!");
                    }
                    str = str.replace(match[0], rp);
                    match = str.match(pRe);                    
                }
                return str;
            };
        },
        Extends: j2j.patterns.Singleton
    });
	Package("j2j.lang").Class("GarbageCollector",{
	GarbageCollector:function(){
		 			var garbage = [];
			var finalize = function(obj){
				 for (var p in obj) {
                    if (obj[p] === obj || p == "constructor") {
                        continue;
                    }
                    if (obj.constructor.prototype[p]) {
                        obj[p] = null;
                    }
                    else {
                        if (obj[p].finalize) {
                            obj[p].finalize();
                        }
                        delete obj[p];
                    }
                    
                }
			};
			this.clean = function(){
				var obj ;
				while(garbage.length){
					obj = garbage.pop();
					finalize(obj);
					delete  obj;
				}
			};
			this.setGC=function(obj){
				garbage.push(obj);
			};
		},
		Extends:j2j.patterns.Singleton
	});
    Package("j2j.lang").Class("System",{
	System:function(){
		             throw Error('u can`t use this funcation directly!');			
        },
        Statics: {
            out: j2j.io.PrintStream.getInstance(),
			gcRunner:j2j.lang.GarbageCollector.getInstance(),
			setGC: function(obj){
				this.gcRunner.setGC(obj);
			},
			gc: function(){
				this.gcRunner.clean();
			}
			
        }
    });
	Package.namespace("j2j.lang").exportTo(window);
})();